home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / editors / mjovesrc.zoo / scandir.c < prev    next >
C/C++ Source or Header  |  1992-04-04  |  5KB  |  229 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. /*
  9.  * This file is used as a compiled module by Jove and also included as
  10.  * source in recover.c
  11.  */
  12. #ifndef TUNED
  13. # include "jove.h"
  14. #endif
  15. #include "scandir.h"
  16.  
  17. #ifdef    F_COMPLETION
  18.  
  19. #ifdef    MSDOS
  20. # include <dos.h>
  21. # include <search.h>
  22. #endif
  23.  
  24. #ifdef    UNIX
  25. # include <sys/stat.h>
  26. # ifdef    M_XENIX
  27. #  include <sys/ndir.h>
  28. #  ifndef dirent
  29. #   define dirent direct
  30. #  endif
  31. # else
  32. #  ifdef    DIRENT
  33. #   include <dirent.h>
  34. #  else
  35. #   include <sys/dir.h>
  36. #   ifndef dirent
  37. #    define dirent direct
  38. #   endif
  39. #  endif    DIRENT
  40. # endif    /* M_XENIX */
  41. #endif
  42.  
  43. #ifdef    UNIX
  44.  
  45. #define DIRSIZE(entry)    (strlen((entry)->d_name))
  46.  
  47. #if !defined(BSD_DIR) && !defined(DIRENT)
  48.  
  49. typedef struct {
  50.     int    d_fd;        /* File descriptor for this directory */
  51. } DIR;
  52.  
  53. private int
  54. closedir(dp)
  55. DIR    *dp;
  56. {
  57.     (void) close(dp->d_fd);
  58.     free((char *) dp);
  59.     return 0;   /* don't know how to fail */
  60. }
  61.  
  62. private DIR *
  63. opendir(dir)
  64. char    *dir;
  65. {
  66.     DIR    *dp = (DIR *) emalloc(sizeof *dp);
  67.     struct stat    stbuf;
  68.  
  69.     if ((dp->d_fd = open(dir, 0)) == -1)
  70.         return NULL;
  71.     if ((fstat(dp->d_fd, &stbuf) == -1) || !(stbuf.st_mode & S_IFDIR)) {
  72.         closedir(dp);
  73.         return NULL;    /* this isn't a directory! */
  74.     }
  75.     return dp;
  76. }
  77.  
  78. private dirent *
  79. readdir(dp)
  80. DIR    *dp;
  81. {
  82.     static dirent    dir;
  83.  
  84.     do {
  85.         if (read(dp->d_fd, (UnivPtr) &dir, sizeof dir) != sizeof dir)
  86.             return NULL;
  87. #if    defined(elxsi) && defined(SYSV)
  88.     /*
  89.      * Elxsi has a BSD4.2 implementation which may or may not use
  90.      * `twisted inodes' ...  Anyone able to check?
  91.      */
  92.     } while (*(unsigned short *)&dir.d_ino == 0);
  93. #else
  94.     } while (dir.d_ino == 0);
  95. #endif
  96.  
  97.     return &dir;
  98. }
  99.  
  100. #endif    /* ! BSD_DIR */
  101.  
  102. /* Scandir returns the number of entries or -1 if the directory cannoot
  103.    be opened or malloc fails. */
  104.  
  105. int
  106. jscandir(dir, nmptr, qualify, sorter)
  107. char    *dir;
  108. char    ***nmptr;
  109. int    (*qualify) proto((char *));
  110. int    (*sorter) proto((UnivConstPtr, UnivConstPtr));
  111. {
  112.     DIR    *dirp;
  113.     struct  dirent    *entry;
  114.     char    **ourarray;
  115.     unsigned int    nalloc = 10,
  116.             nentries = 0;
  117.  
  118.     if ((dirp = opendir(dir)) == NULL)
  119.         return -1;
  120.     ourarray = (char **) emalloc(nalloc * sizeof (char *));
  121.     while ((entry = readdir(dirp)) != NULL) {
  122.         if (qualify != NULL && (*qualify)(entry->d_name) == 0)
  123.             continue;
  124.         if (nentries == nalloc) {
  125.             ourarray = (char **) realloc((UnivPtr) ourarray, (nalloc += 10) * sizeof (char *));
  126.             if (ourarray == NULL)
  127.                 complain("[Malloc failed: cannot scandir]");
  128.         }
  129.         ourarray[nentries] = (char *) emalloc(DIRSIZE(entry) + 1);
  130.         null_ncpy(ourarray[nentries], entry->d_name, (size_t) DIRSIZE(entry));
  131.         nentries += 1;
  132.     }
  133.     closedir(dirp);
  134.     if ((nentries + 1) != nalloc)
  135.         ourarray = (char **) erealloc((UnivPtr) ourarray,
  136.                     ((nentries + 1) * sizeof (char *)));
  137.     if (sorter != NULL)
  138.         qsort((UnivPtr) ourarray, nentries, sizeof (char **), sorter);
  139.     *nmptr = ourarray;
  140.     ourarray[nentries] = NULL;        /* guaranteed NULL pointer */
  141.  
  142.     return nentries;
  143. }
  144.  
  145. #endif    /* UNIX */
  146.  
  147. #ifdef    MSDOS
  148. # define DIRSIZE(entry)    strlen((entry).name)
  149.  
  150. /* Scandir returns the number of entries or -1 if the directory cannot
  151.    be opened or malloc fails. */
  152.  
  153. unsigned int fmask = _A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SUBDIR;
  154.  
  155. int
  156. jscandir(dir, nmptr, qualify, sorter)
  157. char    *dir;
  158. char    ***nmptr;
  159. int    (*qualify) proto((char *));
  160. int    (*sorter) proto((UnivConstPtr, UnivConstPtr));
  161. {
  162.     char dirname[FILESIZE];
  163.     struct find_t entry;
  164.     char *ptr;
  165.     char    **ourarray;
  166.     unsigned int    nalloc = 10,
  167.             nentries = 0;
  168.  
  169.     strcpy(dirname, dir);
  170.     ptr = &dirname[strlen(dirname)-1];
  171.     if ((dirname[1] == ':' && !dirname[2]) || (*ptr == '/') || (*ptr == '\\'))
  172.        strcat(dirname, "*.*");
  173.     else
  174.        strcat(dirname, "/*.*");
  175.  
  176.     if (_dos_findfirst(dirname, fmask, &entry))
  177.        return -1;
  178.     if ((ourarray = (char **) emalloc(nalloc * sizeof (char *))) == NULL)
  179.     do  {
  180.         if ((fmask == 0x10) && !(entry.attrib&fmask))
  181.             continue;
  182.         strlwr(entry.name);
  183.         if (qualify != NULL && (*qualify)(entry.name) == 0)
  184.             continue;
  185.         if (nentries == nalloc) {
  186.             ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
  187.             if (ourarray == NULL)
  188.                 complain("[Malloc failed: cannot scandir]");
  189.         }
  190.         ourarray[nentries] = (char *) emalloc(DIRSIZE(entry) + 1);
  191.         null_ncpy(ourarray[nentries], entry.name, (int) DIRSIZE(entry));
  192.         nentries++;
  193.     } while (_dos_findnext(&entry) == 0);
  194.  
  195.     if ((nentries + 1) != nalloc)
  196.         ourarray = (char **) erealloc((char *) ourarray,
  197.                     ((nentries + 1) * sizeof (char *)));
  198.     if (sorter != (int (*)())NULL)
  199.         qsort((char *) ourarray, nentries, sizeof (char **), sorter);
  200.     *nmptr = ourarray;
  201.     ourarray[nentries] = NULL;        /* guaranteed NULL pointer */
  202.  
  203.     return nentries;
  204. }
  205.  
  206. #endif    /* MSDOS */
  207.  
  208. void
  209. freedir(nmptr, nentries)
  210. char    ***nmptr;
  211. int    nentries;
  212. {
  213.     char    **ourarray = *nmptr;
  214.  
  215.     while (--nentries >= 0)
  216.         free((UnivPtr) *ourarray++);
  217.     free((UnivPtr) *nmptr);
  218.     *nmptr = NULL;
  219. }
  220.  
  221. int
  222. alphacomp(a, b)
  223. UnivConstPtr    a,
  224.     b;
  225. {
  226.     return strcmp(*(const char **)a, *(const char **)b);
  227. }
  228. #endif /* F_COMPLETION */
  229.